
DEBUG = False

from amplitude.dict import Dict
from win32com import client as w32c
import os, re, sys
from glob import glob

FORMATS = {
    'rtf': 1381254688,
    'icml': 1768123756,
    }

CONSTANTS = Dict(
    DISABLE_DIALOGS = 1699640946,
    ENABLE_DIALOGS = 1699311169,
    CLOSE_SAVE_TRUE = 2036691744,
    CLOSE_SAVE_FALSE = 1852776480,
    CLOSE_SAVE_ASK = 1634954016
    )

class Indesign(Dict):

    def __init__(self, fn):
        self.fn = fn.replace("/", "\\")
        self.app = w32c.Dispatch("InDesign.Application")
        self.app.ScriptPreferences.UserInteractionLevel = CONSTANTS.DISABLE_DIALOGS
        if os.path.exists(fn):
            self.doc = self.app.Open(self.fn)

    def update_links(self):
        for i in range(1, self.doc.Links.Count+1):
            link = self.doc.Links(i)
            try:
                link.update
            except:
                if DEBUG==True: print >> sys.stderr, sys.exc_info()[1]
                pass
    
    def unlink_all(self):
        if DEBUG==True: print 'unlink:', self.doc.Links.Count, 'links'
        for i in range(self.doc.Links.Count,0,-1):
            link = self.doc.Links(i)
            if DEBUG==True: print ' ', i, os.path.basename(link.filePath)
            try:
                link.unlink
            except:
                if DEBUG==True: print >> sys.stderr, sys.exc_info()[1]
                pass

    def insert_page_numbers(self):
        print "inserting page numbers:", os.path.basename(self.fn), '--', len(self.doc.Stories), 'stories',
        self.unlink_all()
        for i in range(self.doc.Stories.Count, 0, -1):
            story = self.doc.Stories(i)
            if DEBUG==True: print i, story.id, '--', len(story.TextContainers), 'text containers,', len(story.Words), 'words,', len(story.Paragraphs), 'paragraphs,', len(story.Tables), 'tables,'
            elif i % 10 == 0: print '.',
            if len(story.Words) > 0 and (len(story.Paragraphs) > 0 or len(story.Tables) > 0):
                for j in range(story.TextContainers.Count, 0, -1):
                    t = story.TextContainers(j)
                    pg = t.ParentPage.Name
                    if pg in ['A', 'B'] or len(t.Words)==0 or len(t.Paragraphs)==0: continue
                    t.Words[0].insertionPoints[0].contents = '[[pg=%s]]' % pg
                    #if DEBUG==True: print ' ', t.Words[0]
        print

    def write_stories(self, path=None, format='icml', search_tag=None, w_page_numbers=False):
        """writes each story. search_tag is an optional string that each story must contain to be exported."""
        if w_page_numbers==True:
            self.insert_page_numbers()

        if path==None: path = os.path.dirname(self.fn)
        fb = os.path.join(path, os.path.basename(os.path.splitext(self.fn)[0]))
        n = self.doc.Stories.Count
        j = 0
        fns = []
        print 'examining', n, 'stories',
        for i in range(1, n+1):
            if i % 100 == 0: print i,
            elif i % 10 == 0: print '.',
            story = self.doc.Stories(i)

            # only include stories that have > 0 words and > 0 (paragraphs or tables)
            paragraphs, tables, words = 0, 0, 0
            for k in range(1, story.TextContainers.Count+1):
                t = story.TextContainers(k)
                words += len(t.Words); paragraphs += len(t.Paragraphs); tables += len(t.Tables)
            content = story.Contents.strip(u'\x18').strip()

            if len(content) > 0 \
            and (search_tag==None or search_tag in content) \
            and words > 0 and (paragraphs > 0 or tables > 0) \
            and (w_page_numbers!=True or '[[pg=' in content):
                j += 1
                fn = fb + "-%03d.%s" % (j, format)
                fns.append(fn)
                if DEBUG==True: print fn
                try:
                    story.Export(FORMATS[format], fn)
                except:
                    print >> sys.stderr, i, fn, sys.exc_info()[1]
                    continue
        print "closing:", os.path.basename(self.fn)
        self.close(save=False)
        print "wrote", len(fns), 'stories'
        return fns

    def close(self, save=None):
        save_options = {True: CONSTANTS.CLOSE_SAVE_TRUE, False: CONSTANTS.CLOSE_SAVE_FALSE, None: CONSTANTS.CLOSE_SAVE_ASK}
        self.doc.Close(save_options[save])
